package com.vercon.moensmart.viewmodel;

import static io.reactivex.plugins.RxJavaPlugins.onSubscribe;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.vercon.common.Constants;
import com.vercon.common.room.entry.AppDataRoomInfo;
import com.vercon.common.utils.APPUtil;
import com.vercon.common.utils.LogUtils;
import com.vercon.common.utils.MirrorDataStorage;
import com.vercon.common.utils.ThreadUtil;
import com.vercon.moensmart.MainActivity;
import com.vercon.moensmart.MainApplication;
import com.vercon.moensmart.mode.AppMode;
import com.vercon.moensmart.mode.response.FollowMember;
import com.vercon.moensmart.mode.response.HealthMeasure;
import com.vercon.moensmart.utils.DefaultMenuUtil;
import com.vercon.moensmart.utils.ToastUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import io.reactivex.Completable;
import io.reactivex.MaybeObserver;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class SystemViewModel extends ViewModel {

    private final String TAG  = SystemViewModel.class.getSimpleName();

    private MutableLiveData<Boolean> isOpenDemistLiveData;
    private MutableLiveData<String> userTokenLiveData;
    private MutableLiveData<Integer> demistTimeLiveData; //单位分钟
    private MutableLiveData<HealthMeasure> healthMeasureLiveData; //最近的测量数据
    private MutableLiveData<String> currentUserIdLiveData; //用户id
    private MutableLiveData<FollowMember> followMemberLiveData; //关心成员
    private MutableLiveData<ArrayList<AppMode>> appModeListLiveData;
    private MutableLiveData<String> websocketLiveData;
    ArrayList<AppMode> mAppModes = new ArrayList<>();
    private String loginUserId = "";
    volatile HashMap<String, AppMode> mHashMap = new HashMap<String, AppMode>();

    public SystemViewModel(){
        isOpenDemistLiveData = new MutableLiveData<>();
        isOpenDemistLiveData.setValue(false);
        userTokenLiveData = new MutableLiveData<>();
        demistTimeLiveData = new MutableLiveData<>();
        demistTimeLiveData.setValue(0);
        healthMeasureLiveData = new MutableLiveData<>();
        currentUserIdLiveData = new MutableLiveData<>();
        followMemberLiveData = new MutableLiveData<>();
        appModeListLiveData = new MutableLiveData<>();
        websocketLiveData = new MutableLiveData<>();
    }

    public MutableLiveData<Boolean> getIsOpenDemist() {
        return isOpenDemistLiveData;
    }

    public void setIsOpenDemist(Boolean isOpenDemist,Integer time) {
        if(!isOpenDemist){
            demistTimeLiveData.setValue(0);
        }else {
            if(time== null || time == 0){
                demistTimeLiveData.setValue(60);
            }else {
                demistTimeLiveData.setValue(time);
            }
        }
        this.isOpenDemistLiveData.postValue(isOpenDemist);
    }

    public MutableLiveData<String> getUserTokenLiveData() {
        userTokenLiveData.setValue(MirrorDataStorage.instance().getString(Constants.STORAGE_KEY_TOKEN));
        return userTokenLiveData;
    }

    public void setUserTokenLiveData(String userToken) {
        this.userTokenLiveData.postValue(userToken);
    }

    public MutableLiveData<Integer> getDemistTimeLiveData() {
        return demistTimeLiveData;
    }

    public void setDemistTimeLiveData(Integer demistTime) {
        this.demistTimeLiveData.postValue(demistTime);
    }

    public Integer demistTimeCountDown() {
        Integer time =  demistTimeLiveData.getValue();
        if(time != null && time != 0){
            time -= 1;
        }
        this.demistTimeLiveData.postValue(time);
        return  time;
    }

    public MutableLiveData<HealthMeasure> getHealthMeasureLiveData() {
        return healthMeasureLiveData;
    }

    public void setHealthMeasureLiveData(HealthMeasure healthMeasure) {
        this.healthMeasureLiveData.postValue(healthMeasure);
    }

    public MutableLiveData<String> getCurrentUserIdLiveData() {
        return currentUserIdLiveData;
    }

    public void setCurrentUserIdLiveData(String currentUserIdLiveData) {
        this.currentUserIdLiveData.postValue(currentUserIdLiveData);
    }

    public MutableLiveData<FollowMember> getFollowMemberLiveData() {
        return followMemberLiveData;
    }

    public void setFollowMemberLiveData(FollowMember followMemberLiveData) {
        this.followMemberLiveData.postValue(followMemberLiveData);
    }

    public String getLoginUserId() {
        return loginUserId;
    }

    public void setLoginUserId(String loginUserId) {
        this.loginUserId = loginUserId;
    }


    public LiveData<ArrayList<AppMode>> getAppModeListLiveData(){
        return appModeListLiveData;
    }


    public synchronized void loadAppModeList(){
        LogUtils.i(TAG, "loadAppModeList");
        synchronized (mAppModes) {
            mAppModes.clear();
            //添加自带菜单
            mAppModes.addAll(DefaultMenuUtil.getAppModesNew(MainActivity.Instance));
            ThreadUtil.getInstance().getExecutorService().execute(new Runnable() {
                @Override
                public void run() {
                    List<PackageInfo> packageInfos = APPUtil.installedAppListIsNotSystem(MainActivity.Instance, null);
                    MainApplication.Companion.getContext().getAppDataBaseInstance().AppDataRoomDao().queryAllDesc()
                            .subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
                            .subscribe(new MaybeObserver<List<AppDataRoomInfo>>() {
                                @Override
                                public void onSubscribe(Disposable d) {

                                }

                                @Override
                                public void onSuccess(List<AppDataRoomInfo> appDataRoomInfos) {
                                    queryAll_data(packageInfos, appDataRoomInfos);
                                }

                                @Override
                                public void onError(Throwable e) {

                                }

                                @Override
                                public void onComplete() {
                                    queryAll_data(packageInfos, null);
                                }
                            });

                }
            });
        }

    }

    private synchronized void queryAll_data(List<PackageInfo> packageInfos,List<AppDataRoomInfo> appDataRoomInfos) {
        // Return a List of all packages that are installed on the device.

        synchronized (mHashMap) {
            try {
                PackageManager pm = MainActivity.Instance.getPackageManager();
                //方便去重
                mHashMap.clear();

                //添加获取系统的应用
                for (PackageInfo info : packageInfos) {
                    Optional<AppMode> option = mAppModes.stream().filter(b -> info.applicationInfo.packageName.equals(b.getPackageName())).findFirst();
                    if (!option.isPresent()) {
                        AppMode appMode = new AppMode();
                        appMode.setPackageName(info.applicationInfo.packageName);
                        appMode.setLabel(info.applicationInfo.loadLabel(pm).toString());
                        appMode.setIcon(info.applicationInfo.loadIcon(pm));
                        appMode.setPackageInfo(info);
                        appMode.setFlags(info.applicationInfo.flags);
                        mHashMap.put(info.applicationInfo.packageName, appMode);
                    }
                }
                Iterator<Map.Entry<String, AppMode>> iterator = mHashMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, AppMode> entry = iterator.next();
                    mAppModes.add(entry.getValue());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            LogUtils.i(TAG, " APP自带+数据库+系统应用：  " + mAppModes.size());
            MainActivity.Instance.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    appModeListLiveData.postValue(mAppModes);
                }
            });

            //过滤第三方下载应用
            try {
                for (AppDataRoomInfo storeData : appDataRoomInfos) {
                    if (mHashMap.get(storeData.getPackageName()) != null) {
                        AppMode appMode = new AppMode();
                        appMode.setInfo(storeData);
                        LogUtils.i("mAppModes", "第三方下载：" + storeData.getName() + "   " + storeData.getPackageName());
                        //mHashMap.put(storeData.getPackageName(), appMode);
                    } else {
                        //下载了包名错误的应用，删除数据，自动显示系统应用；下载了系统内置应用，不显示该应用，且删除数据。
                        LogUtils.i("mAppModes", "删除应用：" + storeData.getName() + "   " + storeData.getPackageName());
                        MainActivity.Instance.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ToastUtils.Companion.showToast(java.lang.String.format("%s %s", storeData.getName(), MainActivity.Instance.getString(com.vercon.common.R.string.no_app)));
                            }
                        });
                        Completable completable = MainApplication.Companion.getContext().getAppDataBaseInstance().AppDataRoomDao().delete(storeData);
                        new CompositeDisposable().add(completable.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe());
                        //删除数据
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public HashMap<String, AppMode> getAppModeMap(){
        return mHashMap;
    }


    public LiveData<String> getWebSocketLiveData(){
        return websocketLiveData;
    }

    public void setWebsocketLiveData(String content){
        websocketLiveData.postValue(content);
    }


}
